﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Atmk.WaterMeter.EF.ModelPuls;
using Atmk.WaterMeter.MIS.Entities.Models;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Hosting;
using NLog;

namespace Atmk.WaterMeter.MIS.TimedTask
{
    public class SettlementService : IHostedService
    {
        private static Timer _timer;
        private static readonly Logger _Logger = LogManager.GetCurrentClassLogger();

        #region Implementation of IHostedService

        /// <summary>
        ///     Triggered when the application host is ready to start the service.
        /// </summary>
        /// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
        public Task StartAsync(CancellationToken cancellationToken)
        {
            ThreadPool.QueueUserWorkItem((state) =>
            {
                _timer = new Timer(Settlement, "", TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(30));
                //_Logger.Info($"{nameof(SettlementService)}-Timer启动");
            });
            return Task.Delay(5, cancellationToken);
        }

        /// <summary>
        ///     Triggered when the application host is performing a graceful shutdown.
        /// </summary>
        /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
        public Task StopAsync(CancellationToken cancellationToken)
        {
            if (_timer != null)
            {
                _timer.Dispose();
                _timer = null;
            }

            return Task.Delay(5, cancellationToken);
        }

        #endregion
        private void Settlement(object state)
        {
            //检查
            _Logger.Debug("自动结算检查时间：" + DateTime.Now.ToString("HH"));
            if (DateTime.Now.ToString("HH") == "02" || DateTime.Now.ToString("HH") == "03")
            {
                using (var context = new atmk_wmdb_devContext())
                {
                    using (var tran = context.Database.BeginTransaction())
                    {
                        Process(context, tran);
                    }
                }
            }
        }

        private void Process(atmk_wmdb_devContext context, IDbContextTransaction tran)
        {
            try
            {
                _Logger.Info($"启动本次结算......" + DateTime.Now.ToString());
                var ProjectId = "434d6136-99f4-414b-bd08-02a27971bc73";
                //所有数据未结算数据
                var settleDays_all = context.SettlementDay.Where(m => m.SettlementState == 0 && m.ReadTime >= DateTime.Now.AddDays(-1).Date && m.Dosage > 0).Take(10000).ToList();
                //按表号分组
                var total_Meter = context.Meter.ToList();
                var prcieStep = context.PrcieStep.Where(m => m.ProjectId == ProjectId).FirstOrDefault();
                var feePrice = context.FeePrice.Where(m => prcieStep.Id == m.PiceStepId).FirstOrDefault();
                //表用量
                var settleDaysGroup = settleDays_all.GroupBy(m => m.CtdeviceId).Select(k =>
                    new Out_SettleDayGroup
                    {
                        meter = total_Meter.FirstOrDefault(m => m.CtdeviceId == k.Key),
                        WaterVolume = Convert.ToDecimal(k.Sum(l => l.Dosage))
                    });
                var settleDayshasOwner = settleDaysGroup.Where(m => m.meter != null);
                var CtdeviceIds = settleDayshasOwner.Select(m => m.meter.CtdeviceId).ToArray();
                var settleDays_list = settleDays_all.Where(m => CtdeviceIds.Contains(m.CtdeviceId)).ToList();

                foreach (var item in settleDayshasOwner)
                {
                    if (item.meter != null)
                    {
                        var orderDetail = new OrderDetail();
                        orderDetail.CostType = 1; //水表扣费
                        orderDetail.RechargeChannels = "水表扣费";
                        orderDetail.WaterVolume = item.WaterVolume;
                        orderDetail.OwnerId = item.meter.OwnerId;
                        orderDetail.MeterNumber = item.meter.MeterNumber;
                        orderDetail.MeterId = item.meter.Id;
                        orderDetail.CreateTime = DateTime.Now;
                        orderDetail.WaterPrice = feePrice.Price1;
                        orderDetail.Money = -item.WaterVolume * feePrice.Price1;
                        if (orderDetail.Money < 0&& item.WaterVolume<999)
                            context.OrderDetail.Add(orderDetail);
                    }
                }
                //改变 “有业主” 该月水表的 结算状态

                foreach (var item in settleDays_list)
                {
                    item.SettlementState = 1;
                }
                context.UpdateRange(settleDays_list);
                var Count = context.SaveChanges();
                tran.Commit();
                _Logger.Info($"条数：" + settleDayshasOwner.Count());
                _Logger.Info($"SaveChanges：" + Count);
                _Logger.Info($"结束本次结算......" + DateTime.Now.ToString());
            }
            catch (Exception ex)
            {
                _Logger.Fatal($"定时结算失败:{ex.Message}");
                tran.Rollback();
            }
        }

    }
}